package services

import (
	"context"
	"fmt"
	"io"
	"log"
	"time"
)

type UserScoreService struct {
}

// 普通批量操作
func (*UserScoreService) GetUserScore(ctx context.Context, request *UserScoreRequest) (*UserScoreResponse, error) {
	fmt.Println("请求用户积分的用户列表GetUserScore：", request.Users)
	var score int32 = 100
	users := make([]*UserInfo, 0)
	for _, user := range request.Users {
		user.UserScore = score
		score++
		users = append(users, user)
	}
	return &UserScoreResponse{Users: users}, nil
}

// 服务端流
func (*UserScoreService) GetUserScoreByServerStream(req *UserScoreRequest, stream UserScoreService_GetUserScoreByServerStreamServer) error {
	fmt.Println("请求用户积分的用户列表GetUserScoreByServerStream：", req.Users)
	var score int32 = 100
	users := make([]*UserInfo, 0)
	for index, user := range req.Users {
		user.UserScore = score
		score++
		users = append(users, user)
		if index > 0 && (index+1)%2 == 0 {
			err := stream.Send(&UserScoreResponse{Users: users})
			if err != nil { //发送出错则终止
				return err
			}
			users = (users)[0:0] //清空
		}
		time.Sleep(time.Second) // 模拟耗时
	}
	if len(users) > 0 { //末尾有数据
		err := stream.Send(&UserScoreResponse{Users: users})
		if err != nil { //发送出错则终止
			return err
		}
	}
	return nil
}

// 客户端流
func (*UserScoreService) GetUserScoreByClientStream(stream UserScoreService_GetUserScoreByClientStreamServer) error {
	var score int32 = 100
	users := make([]*UserInfo, 0)
	for {
		req, err := stream.Recv()
		if err == io.EOF { // 接收完了
			return stream.SendAndClose(&UserScoreResponse{Users: users})
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("客户端流GetUserScoreByClientStream------》", req.Users)
		for _, user := range req.Users {
			user.UserScore = score
			score++
			users = append(users, user)
		}
	}
	return nil
}

// 双向流
func (*UserScoreService) GetUserScoreByTwoStream(stream UserScoreService_GetUserScoreByTwoStreamServer) error {
	var score int32 = 100
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		fmt.Println("双向流流GetUserScoreByTwoStream------》", req.Users)
		users := make([]*UserInfo, 0)
		for _, user := range req.Users { //接收了数据之后可以开启协程去完成其他业务工作
			user.UserScore = score
			score++
			users = append(users, user)
		}
		err = stream.Send(&UserScoreResponse{Users: users})
		if err != nil {
			log.Println(err) //暂时不结束，打印下日志
		}
	}
}
